/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package pobicos;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

/**
 *
 * @author marcin
 */
/*
 * Represents a MyTree of Objects of generic type T. The MyTree is represented as
 * a single rootElement which points to a List<Node<T>> of children. There is
 * no restriction on the number of children that a particular node may have.
 * This MyTree provides a method to serialize the MyTree into a List by doing a
 * pre-order traversal. It has several methods to allow easy updation of Nodes
 * in the MyTree.
 */
public class MyTree<T> {

    private MyNode<T> rootElement;

    /**
     * Default ctor.
     */
    public MyTree() {
        super();
    }

    /**
     * Return the root MyNode of the tree.
     * @return the root element.
     */
    public MyNode<T> getRootElement() {
        return this.rootElement;
    }

    /**
     * Set the root Element for the tree.
     * @param rootElement the root element to set.
     */
    public void setRootElement(MyNode<T> rootElement) {
        this.rootElement = rootElement;
    }

    /**
     * Returns the MyTree<T> as a List of MyNode<T> objects. The elements of the
     * List are generated from a pre-order traversal of the tree.
     * @return a List<Node<T>>.
     */
    public List<MyNode<T>> toList() {
        List<MyNode<T>> list = new ArrayList<MyNode<T>>();
        walk(rootElement, list);
        return list;
    }

    /**
     * Returns a String representation of the MyTree. The elements are generated
     * from a pre-order traversal of the MyTree.
     * @return the String representation of the MyTree.
     */
    public String toString() {
        return toList().toString();
    }
    /**
     * Return the MyNode element which contains specified data
     * @param id
     * @return 
     */
    public MyNode<T> getNodeAt(Integer id) {
        List<MyNode<T>> list = toList();
        for (Iterator<MyNode<T>> it = list.iterator(); it.hasNext();) {
            MyNode<T> myNode = it.next();
            Agent tempAgent = (Agent) myNode.getData();
            if (tempAgent.getId().intValue() == id.intValue()) {
 //               System.out.println("asdasdsd");
                return myNode;
            }
        }
        return null;
    }
    /**
     * @param subNode
     * @return the List of all Nodes in the subTree from given subNode element
     */
    public List<MyNode<T>> getSubtree(MyNode<T> subNode) {
        List<MyNode<T>> list = new ArrayList<MyNode<T>>();
        walk(subNode, list);
        return list;
    }
    /**
     * Deletes the subtree of Nodes from given subNode element
     * @param id 
     */
    public void deleteNode(Integer id) {
        for (MyNode<T> currentData : toList() ) {
                 if(currentData.getChildren().contains(getNodeAt(id))) {
                     currentData.removeChildAt(getNodeAt(id));
                 }
        }
    }
    
    /**
     * Walks the MyTree in pre-order style. This is a recursive method, and is
     * called from the toList() method with the root element as the first
     * argument. It appends to the second argument, which is passed by reference     * as it recurses down the tree.
     * @param element the starting element.
     * @param list the output of the walk.
     */
    private void walk(MyNode<T> element, List<MyNode<T>> list) {
        list.add(element);
        for (MyNode<T> data : element.getChildren()) {
            walk(data, list);
        }
    }
}
/**
 * Represents a node of the MyTree<T> class. The MyNode<T> is also a container, and
 * can be thought of as instrumentation to determine the location of the type T
 * in the MyTree<T>.
 */
